package com.event.management.frontend.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.stp.StpUtil;
import com.event.management.frontend.dto.LoginParam;
import com.event.management.frontend.dto.FrontLoginResponseDTO;
import com.event.management.frontend.dto.FrontUserInfoDTO;
import com.event.management.frontend.dto.RegisterParam;
import com.event.management.frontend.service.LoginLogsService;
import com.event.management.frontend.service.FrontUsersService;
import com.event.management.frontend.common.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * 前台用户认证控制器
 */
@Api(tags = "前台用户认证接口")
@RestController
@RequestMapping("/api/front/auth")
@Slf4j
public class FrontAuthController {

    @Autowired
    private FrontUsersService frontUsersService;
    
    @Autowired
    private LoginLogsService loginLogsService;

    /**
     * 前台用户登录
     * @param loginParam 登录参数
     * @return 登录结果
     */
    @ApiOperation(value = "前台用户登录", notes = "前台用户登录，颁发Token")
    @PostMapping("/login")
    public Result<FrontLoginResponseDTO> login(@RequestBody @Validated LoginParam loginParam) {
        log.info("前台用户登录请求: {}", loginParam.getUsername());
        
        try {
            // 执行登录操作
            FrontLoginResponseDTO loginResponse = frontUsersService.frontLogin(loginParam);
            
            // 记录登录成功日志
            String ipAddress = getRemoteIp();
            loginLogsService.addLoginLog(loginResponse.getUserInfo().getId(), ipAddress, "success");
            
            return Result.ok(loginResponse);
        } catch (Exception e) {
            // 记录登录失败日志
            // 查询用户ID（如果用户存在）
            Integer userId = frontUsersService.getUserIdByUsername(loginParam.getUsername());
            if (userId != null) {
                String ipAddress = getRemoteIp();
                loginLogsService.addLoginLog(userId, ipAddress, "fail");
            }
            
            // 返回错误信息
            log.error("前台用户登录失败: {}", e.getMessage());
            return Result.fail(e.getMessage());
        }
    }
    
    /**
     * 用户注册接口
     * @param registerParam 注册参数
     * @return 注册结果
     */
    @ApiOperation(value = "用户注册", notes = "前台用户注册")
    @PostMapping("/register")
    public Result<Object> register(@RequestBody @Validated RegisterParam registerParam) {
        log.info("用户注册请求: {}", registerParam.getUsername());
        
        try {
            boolean result = frontUsersService.register(registerParam);
            if (result) {
                return Result.ok(null, "注册成功");
            } else {
                return Result.fail("注册失败，请稍后重试");
            }
        } catch (Exception e) {
            log.error("用户注册失败: {}", e.getMessage());
            return Result.fail(e.getMessage());
        }
    }

    /**
     * 前台用户登出
     * @return 登出结果
     */
    @ApiOperation(value = "前台用户登出", notes = "清除当前Token并登出")
    @PostMapping("/logout")
    @SaCheckLogin
    public Result<String> logout() {
        String userId = StpUtil.getLoginIdAsString();
        log.info("前台用户登出: {}", userId);
        StpUtil.logout();
        return Result.ok("登出成功");
    }

    /**
     * 获取当前登录的前台用户信息
     * @return 用户信息
     */
    @ApiOperation(value = "获取当前前台用户信息", notes = "获取当前登录前台用户信息")
    @GetMapping("/me")
    @SaCheckLogin
    public Result<FrontUserInfoDTO> getCurrentUser() {
        FrontUserInfoDTO userInfo = frontUsersService.getCurrentFrontUserInfo();
        return Result.ok(userInfo);
    }
    
    /**
     * 获取远程IP地址
     * @return IP地址
     */
    private String getRemoteIp() {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes != null) {
            HttpServletRequest request = attributes.getRequest();
            String ip = request.getHeader("X-Forwarded-For");
            if (ip != null && !"unknown".equalsIgnoreCase(ip)) {
                // 多次反向代理后会有多个IP值，第一个IP才是真实IP
                int index = ip.indexOf(",");
                if (index != -1) {
                    return ip.substring(0, index);
                } else {
                    return ip;
                }
            }
            ip = request.getHeader("X-Real-IP");
            if (ip != null && !"unknown".equalsIgnoreCase(ip)) {
                return ip;
            }
            return request.getRemoteAddr();
        }
        return "unknown";
    }
} 